package com.mybatis.lo.handler;

import com.mybatis.lo.config.MappedStatement;
import com.mybatis.lo.constant.StatementType;
import com.mybatis.lo.mapping.BoundSql;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import static com.mybatis.lo.constant.StatementType.PREPARED;
import static com.mybatis.lo.constant.StatementType.STATEMENT;

/**
 * 代理模式实现StatementHandler的获取
 * 可在这边做一些通用外置操作等
 * @author zhangbh
 * 2023-06-20 08:17
 **/
public class RoutingStatementHandler implements StatementHandler {

    private StatementHandler delegate;

    public RoutingStatementHandler(MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultSetHandler resultSetHandler, BoundSql boundSql, Object param) {
        StatementType statementType = mappedStatement.getStatementType();
        // todo 这边做简单兼容，如果设置了【statementType=statement】，但是解析出来有【?】则自动转换成 prepare
        if (boundSql.getSql().contains("?") && STATEMENT.equals(statementType)) {
            statementType = PREPARED;
        }
        switch (statementType) {
            case CALLABLE:
                throw new RuntimeException("未实现");
            case STATEMENT:
                delegate = new SimpleStatementHandler(mappedStatement, resultSetHandler, boundSql, param);
                break;
            case PREPARED:
                delegate = new PreparedStatementHandler(mappedStatement, parameterHandler, resultSetHandler, boundSql, param);
                break;
        }
    }

    @Override
    public Statement prepare(Connection connection) throws SQLException {
        return delegate.prepare(connection);
    }

    @Override
    public void parameterize(Statement statement) throws SQLException {
        delegate.parameterize(statement);
    }

    @Override
    public <T> List<T> query(Statement statement) throws SQLException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        return delegate.query(statement);
    }
}
